package com.utility.project.common.base;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.utility.project.common.constants.HttpCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * @author wangjiyun
 * @date 2022/12/27 15:26
 * @description 全局异常处理
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 业务异常
     */
    @ExceptionHandler(ServiceException.class)
    public R<String> handleServiceException(HttpServletRequest req, ServiceException e) {
        log.error(req.getRequestURI() + ":系统业务异常 : ", e);
        return R.fail(e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(MismatchedInputException.class)
    public R<String> handleServiceException(HttpServletRequest req, MismatchedInputException e) {
        log.error(req.getRequestURI() + ":参数不匹配error : ", e);
        return R.fail(HttpCodeEnum.INVALID_REQUEST.getCode(), e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public R<String> handleIllegalArgumentException(HttpServletRequest req, IllegalArgumentException e) {
        log.error(req.getRequestURI() + ":参数非空判断error : ", e);
        return R.fail(HttpCodeEnum.NOT_FOUND.getCode(), e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public R<String> handleMissingServletRequestParameterException(HttpServletRequest req, MissingServletRequestParameterException e) {
        log.error(req.getRequestURI() + ":缺少参数 : ", e);
        return R.fail(HttpCodeEnum.INVALID_REQUEST.getCode(), e.getMessage());
    }

    /**
     *
     * @author wangjiyun
     * @date 2023/1/6 11:16
     * @param e mvc参数校验异常
     * @return 处理后的前端结果
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<String> handleServiceException(HttpServletRequest req,MethodArgumentNotValidException e) {
        String message = e.getMessage();
        log.error(req.getRequestURI() + ":参数校验异常error : ", e);
        // 提取有效地错误信息，返回给前端
        if (StrUtil.isNotEmpty(message)) {
            int index = message.lastIndexOf("default message");
            if (index > 0) {
                message = message.substring(index).replace("default message", "").replaceAll("\\[", "")
                    .replaceAll("]", "").trim();
            }
        }
        return R.fail(HttpCodeEnum.UNPROCESABLE_ENTITY.getCode(), message);
    }


    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public R<String> handleException(Exception e, HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestUri, e);
        return R.fail("内部错误");

    }
}
